﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using vudu.Presentacion.Contrato.VU_03_Gestionar_Pensum_por_Escuela;
using vudu.Logica.Fachada;
using vudu.ClasesDominio;
using System.Web.UI.WebControls;
using System.Data;

namespace vudu.Presentacion.Presentador.VU_03_Gestionar_Pensum_por_Escuela
{
    public class PresentadorAgregarPrelacion
    {
        #region atributos privados

        private IContratoAgregarPrelacion _vista;
        private EnlaceLogico _fachada;
        private Pensum _pensumActual;
        private Materia _materiaActual;
        private string _rol;

        #endregion

        #region Constructor

        public PresentadorAgregarPrelacion(IContratoAgregarPrelacion vista)
        {
            _vista = vista;
            _fachada = (EnlaceLogico)vista.Sesion["Fachada"];
            _rol = (string)_vista.Sesion["TipoRol"];
            _pensumActual = (Pensum)_vista.Sesion["PensumAConsultar"];
            _materiaActual = (Materia)_vista.Sesion["MateriaActual"];
            _vista.TablaPrelaciones.Enabled = false;
        }

        #endregion

        #region Propiedades

        public Pensum PensumActual
        {
            get { return _pensumActual; }
            set { _pensumActual = value; }
        }

        public Materia MateriaActual
        {
            get { return _materiaActual; }
            set { _materiaActual = value; }
        }


        public string Rol
        {
            get { return _rol; }
            set { _rol = value; }
        }

        #endregion

        #region Metodos

        /// <summary>
        /// metodo que se encarga de escribir el nombre del usuario logeado
        /// </summary>
        public void MostrarNombreUsuario()
        {
            Escuela esc = (Escuela)_fachada.RolActual;
            _vista.Actor.Text = _rolUsuario + _separador + esc.NombreEscuela;
        }

        /// <summary>
        /// metodo que seencargade cargar las materias de uns emestre seleccionado
        /// </summary>
        public void CargarMateriasDePensumPorSemestre()
        {
            List<Prelacion> semestre = new List<Prelacion>();
            List<Prelacion> semestresInferiores = new List<Prelacion>();
            int numSemestre = ObtenerNumeroDeSemestre();
            semestre = _fachada.ConsultarMateriasDePensumPorSemestre(_pensumActual, numSemestre);
            this.CargarTablaMateriasPensum(semestre);
            //this.CargarTablaMateriasSemestresBajos(semestresInferiores);
            this.CargarTablaPrelacionesVacia();
        }

        /// <summary>
        /// metodo que se encarga de obteenr el numero de semestre escogido
        /// </summary>
        /// <returns>numero de semestre</returns>
        private int ObtenerNumeroDeSemestre()
        {
            int numSemestre = 0;
            try
            {
                numSemestre = int.Parse(_vista.Lista.SelectedValue);
                numSemestre = numSemestre + 1;
            }
            catch (Exception)
            {
                OcurreError(_mensajeError2);//excepcion inesperada
            }
            return numSemestre;
        }

        /// <summary>
        /// metodo que se encarga de calcular la diferencia entre el numero de materias traidas y el numero de filas total(8)
        /// para ayudar a rellenar las filas vacias del gridview de materia
        /// </summary>
        /// <param name="totalFilas"></param>
        /// <returns></returns>
        private int Diferencia(int totalFilas)
        {
            int diferencia = 0;
            if (totalFilas < _vista.TablaMaterias.PageSize)
            {
                diferencia = _vista.TablaMaterias.PageSize - totalFilas;
            }
            return diferencia;
        }

        /// <summary>
        /// Metodo que se encarga de obtener la materia encapsulada en el objeto prelacion
        /// de la lista de semestres(objeto prelacion encapsulala materia, 
        /// su numero de semestre y lista de materias)
        /// </summary>
        /// <param name="materiaSemestre">objeto prelacion encapsulado</param>
        /// <returns>objeto materia seleccionado
        /// </returns>
        private Materia ObtenerMateriaDePrelacion(Prelacion materiaSemestre)
        {
            Materia materia = new Materia();
            if (materiaSemestre != null)
            {
                materia = materiaSemestre.MiMateriaPensum;
            }
            return materia;
        }

        /// <summary>
        /// Carga el Gridview de las materias que tiene el pensum hasta los momentos en orden de semestre
        /// </summary>
        public void CargarTablaMateriasPensum(List<Prelacion> materiasSemestre)
        {
            DataTable table = new DataTable();
            int diferencia = 6;
            table.Columns.Add("Nombre", typeof(string));
            table.Columns.Add("Codigo", typeof(string));
            table.Columns.Add("U.C.", typeof(string));
            
            try
            {
                if (materiasSemestre != null)
                {
                    diferencia = Diferencia(materiasSemestre.Count);
                    foreach (Prelacion materiaSemestre in materiasSemestre)
                    {
                        Materia materia = this.ObtenerMateriaDePrelacion(materiaSemestre);

                        if (materia != null)
                        {
                            table.Rows.Add(materia.Nombre, materia.Codigo, materia.NumeroCreditos);
                        }
                    }

                }
                for (int i = 0; i < diferencia; i++)
                {
                    table.Rows.Add("-", "-", "-");
                }
                this._vista.TablaMaterias.DataSource = table;
                this._vista.TablaMaterias.DataBind();

            }
            catch (Exception)
            {
                OcurreError(_mensajeError2);//excepcion inesperada
            }

        }


        /// <summary>
        /// Carga el Gridview de las materias que tiene el pensum hasta los momentos en orden de semestre
        /// </summary>
        public void CargarTablaPrelacionesVacia()
        {
            DataTable table = new DataTable();
            table.Columns.Add("Nombre", typeof(string));
            table.Columns.Add("Codigo", typeof(string));
            table.Columns.Add("U.C.", typeof(string));
            table.Columns.Add("Semestre", typeof(string));

            for (int i = 0; i < _vista.TablaPrelaciones.PageSize; i++)
            {
                table.Rows.Add("-", "-", "-", "-");
            }

            this._vista.TablaPrelaciones.DataSource = table;
            this._vista.TablaPrelaciones.DataBind();

        }


        /// <summary>
        /// Carga el Gridview de las materias que tiene el pensum hasta los momentos en orden de semestre
        /// </summary>
        public void CargarTablaMateriasSemestresBajos(List<Prelacion> materiasSemestre)
        {
            DataTable table = new DataTable();
            int diferencia = 6;
            table.Columns.Add("Nombre", typeof(string));
            table.Columns.Add("Codigo", typeof(string));
            table.Columns.Add("U.C.", typeof(string));
            table.Columns.Add("Semestre", typeof(string));

            try
            {
                if (materiasSemestre != null)
                {
                    diferencia = Diferencia(materiasSemestre.Count);
                    foreach (Prelacion materiaSemestre in materiasSemestre)
                    {
                        Materia materia = this.ObtenerMateriaDePrelacion(materiaSemestre);

                        if (materia != null)
                        {
                            table.Rows.Add(materia.Nombre, materia.Codigo, materia.NumeroCreditos, materiaSemestre.SemestreMateriaPensum);
                        }
                    }

                }
                for (int i = 0; i < diferencia; i++)
                {
                    table.Rows.Add("-", "-", "-", "-");
                }
                this._vista.TablaPrelaciones.DataSource = table;
                this._vista.TablaPrelaciones.DataBind();

            }
            catch (Exception)
            {
                OcurreError(_mensajeError2);//excepcion inesperada
            }

        }

        /// <summary>
        /// Metodo que imprime un mensaje en la pagina al ocurrir un error
        /// </summary>
        /// <param name="info">
        /// mensaje de error
        /// </param>
        public void OcurreError(string info)
        {
            _vista.Error.Text =  info;
            _vista.Error.ForeColor = System.Drawing.Color.Red;
            _vista.Error.Visible = true;
        }

        public void OcurreExito(string info)
        {
            _vista.Error.Text =  info;
            _vista.Error.CssClass = "transaccionExitosa";
            _vista.Error.ForeColor = System.Drawing.Color.Green;
            _vista.Error.Visible = true;
        }

        /// <summary>
        /// Metodo que se encarga de del control de la paginacion del gridview
        /// de materis a escoger para armar sus prelaciones
        /// </summary>
        /// <param name="e">
        /// evento que controla la paginacion del gridview de materias a escoger</param>
        public void PaginacionMaterias(GridViewPageEventArgs e)
        {
            int numSemestre = ObtenerNumeroDeSemestre();
            List<Prelacion> semestre = _fachada.ConsultarMateriasDePensumPorSemestre(_pensumActual, numSemestre);
            _vista.TablaMaterias.PageIndex = e.NewPageIndex;
            CargarTablaMateriasPensum(semestre);
            
        }

        /// <summary>
        /// Metodo que se encarga de del control de la paginacion del gridview
        /// de materias de semestres inferiores para escoger prelacion
        /// </summary>
        /// <param name="e">
        /// evento que controla la paginacion del gridview de materias a escoger</param>
        public void PaginacionPrelaciones(GridViewPageEventArgs e)
        {
            int numSemestre = ObtenerNumeroDeSemestre();
            List<Prelacion> semestres = _fachada.ConsultarMateriasDeSemestresInferiores(_pensumActual, numSemestre,_materiaActual);
            _vista.TablaPrelaciones.PageIndex = e.NewPageIndex;
            this.CargarTablaMateriasSemestresBajos(semestres);
            _vista.TablaPrelaciones.Enabled = true;
        }

        /// <summary>
        /// metodo que se encarga de selesccionar la materia para asignarle
        /// prelaciones, inabilita la tabla de amterias y habilita la de prelaciones
        /// </summary>
        /// <param name="sender">objeto que disparo el evento</param>
        public void SeleccionarMateriaParaPrelacion(object sender)
        {
            CheckBox chequear = (CheckBox)sender;
            if (chequear.Checked)
            {
                MateriaActual = ConsultarUnaMateria();
                //llenar materia prelaciones
                int numSem = ObtenerNumeroDeSemestre();
                List<Prelacion> prelaciones = _fachada.ConsultarMateriasDeSemestresInferiores(_pensumActual, numSem, MateriaActual);
                if (prelaciones != null)
                {
                    if (prelaciones.Count > 0)
                    {
                        this.CargarTablaMateriasSemestresBajos(prelaciones);
                        _vista.TablaPrelaciones.Enabled = true;
                        _vista.TablaMaterias.Enabled = false;
                    }
                    else
                    {
                        //mostrar mensaje de que no tiene mas prelaciones posibles
                    }
                }
                //bloquear gridview1 excepto estamateria
            }
        }

        
        /// <summary>
        /// metodo que se encarga de agregar las prelaciones
        /// una ves seleccionada la opcion
        /// </summary>
        public void AgregarPrelacionesAMateria()
        {
            if (_materiaActual != null)
            {
                List<Materia> prelaciones = new List<Materia>();
                bool operacion = false;
                prelaciones = ObtenerPrelacionesSeleccionadas();
                if (prelaciones != null)
                {
                    operacion = _fachada.InsertarPrelacionesDeMateria(_materiaActual, prelaciones, _pensumActual);
                    if (operacion)
                    {
                        _materiaActual = null;
                        OcurreExito(_mensajeExito1);
                    }
                    else
                    {
                        OcurreError(_mensajeError3);
                    }
                    _vista.TablaMaterias.Enabled = true;
                    _vista.TablaPrelaciones.Enabled = false;
                }
                else
                {
                    OcurreError(_mensajeError5);//debe seleccionar alguna prelacion
                }
                
            }
            else
            {
                OcurreError(_mensajeError4);//debe escoger alguna materia
            }
        }
        /// <summary>
        /// metodo que se encarga de extraer las amterias seleccionadas del gridview de prelaciones
        /// </summary>
        /// <returns>lista dematerias escogidas</returns>
        private List<Materia> ObtenerPrelacionesSeleccionadas()
        {
            List<Materia> prelaciones = new List<Materia>();

            foreach (GridViewRow row in _vista.TablaPrelaciones.Rows)
            {
                CheckBox check = row.FindControl("chkSeleccionEscogerPrelacion") as CheckBox;
                if (check.Checked)
                {
                    Materia matAux = new Materia();
                    matAux = ObtenerMateriaDeFila(row);
                    if(matAux!= null)
                        prelaciones.Add(matAux);
                }
            }
            if (prelaciones.Count == 0)
                prelaciones = null;
            return prelaciones;
        }

        /// <summary>
        /// Metodo que se encarga de obtener y encapsultar la amteria del gridview de materias
        /// junto al numero de semestre que le estoy pasando
        /// </summary>
        /// <param name="row">fila donde se encuentra la materia escogida</param>
        /// <param name="numSemestre">semestre al cual pertenecera</param>
        /// <returns>objeto materia encapsulado con su semestre</returns>
        private Materia ObtenerMateriaDeFila(GridViewRow row)
        {
            Materia mat = new Materia();
            string nombreMat = row.Cells[1].Text;
            string codMat = row.Cells[2].Text;
            string uc = row.Cells[3].Text;
            try
            {
                if (!uc.Contains('-') && !codMat.Contains('-'))
                {
                    mat.Nombre = nombreMat;
                    mat.Codigo = int.Parse(codMat);
                    mat.NumeroCreditos = int.Parse(uc);
                }
                else
                    mat = null;
            }
            catch (Exception)
            {
                OcurreError(_mensajeError2);//excepcion inesperada
            }
            return mat;
        }

        /// <summary>
        /// metodo que retorna el objetomateria seleccionado del gridview 1
        /// </summary>
        /// <returns></returns>
        private Materia ConsultarUnaMateria()
        {
            Materia materiaSeleccionada = new Materia();
            if (_pensumActual != null)
            {
                try
                {
                    foreach (GridViewRow row in _vista.TablaMaterias.Rows)
                    {
                        CheckBox check = row.FindControl("chkSeleccion") as CheckBox;
                        if (check.Checked)
                        {
                            Materia matAux = new Materia();
                            matAux = ObtenerMateriaDeFila(row);
                            if (matAux != null)
                                materiaSeleccionada = matAux;
                        }
                    }

                }
                catch (Exception)
                {
                    OcurreError(_mensajeError2);
                }
            }
            return materiaSeleccionada;
        }

        /// <summary>
        /// metodo que se encarga de cancelar la escoger las prelaciones para una materia
        /// </summary>
        public void CancelarPrelacion()
        {
            this.CargarTablaPrelacionesVacia();
            this.CargarMateriasDePensumPorSemestre();
            _vista.TablaMaterias.Enabled = true;
            _vista.TablaPrelaciones.Enabled = false;
        }

        #endregion

        #region Constantes

        private const string _paginaActual = "CrearPensumEtapaIII.aspx";
        private const string _paginaSiguiente = "";//HOMEESCUELA
        private const string _mensajeExito1 = "Operacion Exitosa: Se ha asignado la prelacion exitosamente";
        private const string _mensajeError2 = "Operacion Fallida: Ha Ocurrido una Excepcion Inesperada";
        private const string _mensajeError3 = "Operacion Fallida: Ha ocurrido un error en la asignacion de prelaciones";
        private const string _mensajeError4 = "Operacion Fallida: Debe seleccionar una materia";
        private const string _mensajeError5 = "Operacion Fallida: Debe seleccionar alguna prelacion";
        private const string _rolUsuario = "Escuela";
        private const string _separador = ": ";

        #endregion
    }
}